//SPDX-FileCopyrightText: Copyright 2025-2025 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package board_api_serv

import (
	"context"
	"time"

	"gitcode.com/eteam/api-server/dao"
	"gitcode.com/eteam/api-server/dao/board_dao"
	"gitcode.com/eteam/api-server/notice_serv"
	"gitcode.com/eteam/proto-gen-go.git/board_api"
	"gitcode.com/eteam/proto-gen-go.git/notices/notices_board"
	"github.com/google/uuid"
	"go.mongodb.org/mongo-driver/mongo"
)

func (apiImpl *BoardApiImpl) AddLlm(ctx context.Context, req *board_api.AddLlmRequest) (*board_api.AddLlmResponse, error) {
	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &board_api.AddLlmResponse{
			Code:   board_api.AddLlmResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}
	//检查board成员权限
	memberItem, err := board_dao.MemberInfoDao.Get(ctx, req.BoardId, sessItem.UserId)
	if err != nil {
		return &board_api.AddLlmResponse{
			Code:   board_api.AddLlmResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}
	if !(memberItem.Admin) {
		return &board_api.AddLlmResponse{
			Code:   board_api.AddLlmResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	llmId := uuid.NewString()
	nowTime := time.Now().UnixMilli()

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = board_dao.BoardLlmDao.Insert(sessCtx, &board_dao.LlmInfoDbItem{
			LlmId:   llmId,
			BoardId: req.BoardId,
			BasicInfo: board_dao.BasicLlmInfoDbItem{
				Name:             req.BasicInfo.Name,
				ApiKey:           req.BasicInfo.ApiKey,
				ApiAddr:          req.BasicInfo.ApiAddr,
				SystemPrompt:     req.BasicInfo.SystemPrompt,
				DefaultModelName: req.BasicInfo.DefaultModelName,
			},
			CreateTime: nowTime,
			UpdateTime: nowTime,
		})
		if err != nil {
			return nil, err
		}
		return &board_api.AddLlmResponse{
			Code:  board_api.AddLlmResponse_CODE_OK,
			LlmId: llmId,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	//发送通知
	go notice_serv.PublishToBoard(req.BoardId, &notices_board.UpdateBoardNotice{
		BoardId: req.BoardId,
	})
	return ret.(*board_api.AddLlmResponse), nil
}

func (apiImpl *BoardApiImpl) UpdateLlm(ctx context.Context, req *board_api.UpdateLlmRequest) (*board_api.UpdateLlmResponse, error) {
	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &board_api.UpdateLlmResponse{
			Code:   board_api.UpdateLlmResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}

	//检查board成员权限
	memberItem, err := board_dao.MemberInfoDao.Get(ctx, req.BoardId, sessItem.UserId)
	if err != nil {
		return &board_api.UpdateLlmResponse{
			Code:   board_api.UpdateLlmResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}
	if !(memberItem.Admin) {
		return &board_api.UpdateLlmResponse{
			Code:   board_api.UpdateLlmResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	exist, err := board_dao.BoardLlmDao.Exist(ctx, req.BoardId, req.LlmId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &board_api.UpdateLlmResponse{
			Code:   board_api.UpdateLlmResponse_CODE_NO_LLM,
			ErrMsg: "大模型配置不存在",
		}, nil
	}

	nowTime := time.Now().UnixMilli()

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = board_dao.BoardLlmDao.UpdateBasic(sessCtx, req.BoardId, req.LlmId, &board_dao.BasicLlmInfoDbItem{
			Name:             req.BasicInfo.Name,
			ApiKey:           req.BasicInfo.ApiKey,
			ApiAddr:          req.BasicInfo.ApiAddr,
			SystemPrompt:     req.BasicInfo.SystemPrompt,
			DefaultModelName: req.BasicInfo.DefaultModelName,
		}, nowTime)
		if err != nil {
			return nil, err
		}
		return &board_api.UpdateLlmResponse{
			Code: board_api.UpdateLlmResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	//发送通知
	go notice_serv.PublishToBoard(req.BoardId, &notices_board.UpdateBoardNotice{
		BoardId: req.BoardId,
	})
	return ret.(*board_api.UpdateLlmResponse), nil
}

func (apiImpl *BoardApiImpl) RemoveLlm(ctx context.Context, req *board_api.RemoveLlmRequest) (*board_api.RemoveLlmResponse, error) {
	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &board_api.RemoveLlmResponse{
			Code:   board_api.RemoveLlmResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		}, nil
	}

	//检查board成员权限
	memberItem, err := board_dao.MemberInfoDao.Get(ctx, req.BoardId, sessItem.UserId)
	if err != nil {
		return &board_api.RemoveLlmResponse{
			Code:   board_api.RemoveLlmResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}
	if !(memberItem.Admin) {
		return &board_api.RemoveLlmResponse{
			Code:   board_api.RemoveLlmResponse_CODE_NO_PERMISSION,
			ErrMsg: "没有权限",
		}, nil
	}

	exist, err := board_dao.BoardLlmDao.Exist(ctx, req.BoardId, req.LlmId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &board_api.RemoveLlmResponse{
			Code: board_api.RemoveLlmResponse_CODE_OK,
		}, nil
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		return nil, err
	}
	defer dao.EndSession(dbSess)

	ret, err := dbSess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) (interface{}, error) {
		err = board_dao.BoardLlmDao.Remove(sessCtx, req.BoardId, req.LlmId)
		if err != nil {
			return nil, err
		}
		return &board_api.RemoveLlmResponse{
			Code: board_api.RemoveLlmResponse_CODE_OK,
		}, nil
	})
	if err != nil {
		return nil, err
	}
	//发送通知
	go notice_serv.PublishToBoard(req.BoardId, &notices_board.UpdateBoardNotice{
		BoardId: req.BoardId,
	})
	return ret.(*board_api.RemoveLlmResponse), nil
}
